package com.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;

import javax.servlet.http.HttpServletResponse;
import java.util.function.Consumer;
import java.util.function.Function;

public class Utility {
    public static String errBadRequest() {
        return errBadRequest("\"value\" field is required");
    }

    public static String errBadRequest(String message) {
        return JSON.toJSONString(new Object() {
            public final int code = HttpServletResponse.SC_BAD_REQUEST;
            public final String err = message;
        });
    }

    public static String errInternalError(String message) {
        return JSON.toJSONString(new Object() {
            public final int code = HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
            public final String err = message;
        });
    }


    public static <T> String parsePayloadToClassThen(String payloadJSON, Class<T> payloadClass, Function<T, String> operation) {
        String response;
        T value;

        try {
            JSONObject cmd = JSON.parseObject(payloadJSON);
            value = cmd.getObject("value", payloadClass);
            if (value == null) {
                throw new JSONException(payloadJSON + " does not have a required \"value\" field");
            }
        } catch (JSONException ignored) {
            return errBadRequest();
        }

        try {
            response = operation.apply(value);
        } catch (RuntimeException err) {
            return errInternalError(err.getMessage());
        }

        return response;
    }

    public static String parsePayloadToStringThenUpdate(String payload, Consumer<String> update) {
        return parsePayloadToClassThen(payload, String.class, str -> {
            update.accept(str);
            return "ok";
        });
    }

    public static <T> String parsePayloadToStringThenQuery(String payload, Function<String, T> then) {
        return parsePayloadToClassThen(payload, String.class, str -> JSON.toJSONString(then.apply(str)));
    }
}
